/*-
 * See the file LICENSE for redistribution information.
 *
 * Copyright (c) 2002, 2012 Oracle and/or its affiliates.  All rights reserved.
 *
 */

package persist.sqlapp;

import java.io.File;

import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.persist.EntityCursor;
import com.sleepycat.persist.EntityStore;
import com.sleepycat.persist.ForwardCursor;
import com.sleepycat.persist.StoreConfig;

/**
 * An example shows how some common SQL queries are implemented using DPL.
 *
 * @see #usage
 *
 * @author chao
 */
public class RadiusSQL {

    private static String envDir = "g:/tmp";
    private static boolean cleanEnvOnExit = false;
    private static Environment env = null;
    private static EntityStore store = null;
    private static RediusDao dao = null;

    /**
     * Setup a Berkeley DB engine environment, and preload some example records.
     *
     * @throws com.sleepycat.je.DatabaseException
     */
    public void setup()
        throws DatabaseException {

        /* Open a transactional Berkeley DB engine environment. */
        EnvironmentConfig envConfig = new EnvironmentConfig();
        envConfig.setAllowCreate(true);
        envConfig.setTransactional(false);
        env = new Environment(new File(envDir), envConfig);

        /* Open a transactional entity store. */
        StoreConfig storeConfig = new StoreConfig();
        storeConfig.setAllowCreate(true);
        storeConfig.setTransactional(false);
        store = new EntityStore(env, "RadiusSQL", storeConfig);

        /* Initialize the data access object. */
                
        dao = new RediusDao(store);

        /* Preload some example records. */
        loadRediusLogDb();
    }

    /* Load the department database. */
    private void loadRediusLogDb()
        throws DatabaseException {
    	int count = 3;
    	long tagTime = System.currentTimeMillis();
    	for (int i = 0; i < count; i++) {
    		dao.RediusByIp.put(new RediusLog(i,count+1-i,i,Math.random()+""));
		}
    	tagTime = System.currentTimeMillis()-tagTime+1;
    	System.out.format("count:%s time:%s speed:%s\n",count,tagTime,(count*1000)/tagTime);
    	
    }

  

    /** Run the SQL examples. */
    public void runApp()
        throws DatabaseException {

        /* Print departmemt database contents order by departmentId. */
        System.out.println("SELECT * FROM RediusLog ORDER BY ip;");
        printQueryResults(dao.RediusByIp.entities());
            
        
        System.out.println("SELECT * FROM RediusLog WHERE ip = 1");
        RediusLog rediusLog = dao.RediusByIp.get(1);        
        System.out.println(rediusLog);
        System.out.println();

        /* Print departmemt database contents order by departmentName. */
        System.out.println("SELECT * FROM RediusLog " + "ORDER BY online;");
        printQueryResults(dao.RediusByOnline.entities());

        /* Print employee database contents order by employeeId. */
        System.out.println("SELECT * FROM RediusLog ORDER BY offline;");
        printQueryResults(dao.RediusByOffline.entities());

        /* Do a prefix query. */
        System.out.println("SELECT * FROM RediusLog WHERE id " + "LIKE 'M%';");
        printQueryResults(dao.doPrefixQuery(dao.RediusById, "M"));

        /* Do a range query. */
        System.out.println("SELECT * FROM RediusLog WHERE online >= 6000 AND " + "online <= 8000;");
        
        int count = 1;
        long tagTime = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            printQueryResults(dao.doRangeQuery(dao.RediusByOnline,
                    new Integer(i), //fromKey
                    true, //fromInclusive
                    new Integer(i+1), //toKey
                    true)); //toInclusive			
		}
    	
        tagTime = System.currentTimeMillis() - tagTime + 1;
        
        System.out.format("count:%s time:%s speed:%s\n",count,tagTime,(count*1000)/tagTime);
    }

    /** Print query results. */
    public <V> void printQueryResults(ForwardCursor<V> cursor)
        throws DatabaseException {

        try {
            for (Object entity : cursor) {
                System.out.println(entity);
            }
            System.out.println();
        } finally {
            cursor.close();
        }
    }

    /**
     * Close the store and environment.
     */
    public void close() {

        if (store != null) {
            try {
                store.close();
            } catch (DatabaseException dbe) {
                System.err.println("Error closing store: " +
                        dbe.toString());
                System.exit(-1);
            }
        }

        if (env != null) {
            try {
                // Finally, close environment.
                env.close();
            } catch (DatabaseException dbe) {
                System.err.println("Error closing env: " +
                        dbe.toString());
                System.exit(-1);
            }
        }

        if (cleanEnvOnExit) {
            removeDbFiles();
        }
    }

    private void removeDbFiles() {
        File file = new File(envDir);
        for (File f : file.listFiles()) {
            f.delete();
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        
        /* Parse the arguments list. */
        parseArgs(args);

        try {
            RadiusSQL s = new RadiusSQL();
            s.setup();
            s.runApp();
            s.close();
        } catch (DatabaseException e) {
            e.printStackTrace();
            System.exit(-1);
        }
    }

    /* Parse input arguments. */
    private static void parseArgs(String args[]) {
        for(int i = 0; i < args.length; ++i) {
            if (args[i].startsWith("-")) {
                switch(args[i].charAt(1)) {
                  case 'h':
                    envDir = args[++i];
                    break;
                  case 'd':
                    cleanEnvOnExit = true;
                    break;
                  default:
                    usage();
                }
            }
        }
    }

    private static void usage() {
        System.out.println("Usage: java RadiusSQL" +
                           "\n [-h <env directory>] " +
                           "# environment home directory" +
                           "\n [-d] # clean environment after program exits");
        System.exit(-1);
    }
}
